package com.ying.service.order.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import com.ying.core.exception.CustomException;
import com.ying.core.page.PageData;
import com.ying.core.page.PageWrap;
import com.ying.core.response.ResultCode;
import com.ying.dao.order.ExpressRepository;
import com.ying.dao.system.RoleRepository;
import com.ying.dao.system.UserRepository;
import com.ying.po.order.Express;
import com.ying.po.order.Order;
import com.ying.po.order.Seller;
import com.ying.po.system.Role;
import com.ying.service.order.ExpressService;
import com.ying.service.system.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ExpressServiceImpl implements ExpressService {

    @Autowired
    private ExpressRepository expressRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private UserService userService;

    @Override
    public Integer create(Express express) {
        if (express.getId() != null) {
            Optional<Express> optional = expressRepository.findById(express.getId());
            if (optional.isPresent()) {
                throw new CustomException(ResultCode.DATA_ALREADY_EXISTED, "ExpressServiceImpl.create");
            }
        }
        return expressRepository.save(express).getId();
    }

    @Override
    public void deleteById(Integer id) {
        // 参数检验----------------------------------
        if (id == null)
            throw new CustomException(ResultCode.PARAM_IS_BLANK, "ExpressServiceImpl.deleteById");
        Optional<Express> optional = expressRepository.findById(id);
        if (!optional.isPresent()) {
            throw new CustomException(ResultCode.RESULE_DATA_NONE, "ExpressServiceImpl.deleteById");
        }
        // ------------开始业务----------------------
        Express express = optional.get();
        express.setIsDelete(1);
        expressRepository.save(express);
    }

    @Override
    public void deleteByIdInBatch(List<Integer> ids) {
        // 参数检验----------------------------------
        if (CollUtil.isEmpty(ids))
            throw new CustomException(ResultCode.PARAM_IS_BLANK, "ExpressServiceImpl.deleteByIdInBatch");
        // ------------开始业务----------------------
        for (Integer id: ids) {
            this.deleteById(id);
        }
    }

    @Override
    public void updateById(Express express) {
        // -------------------参数检验---------------------
        if (express.getId() == null) {
            throw new CustomException(ResultCode.PARAM_IS_BLANK, "ExpressServiceImpl.updateById");
        }
        Optional<Express> optional = expressRepository.findById(express.getId());
        if (!optional.isPresent()) {
            throw new CustomException(ResultCode.RESULE_DATA_NONE, "ExpressServiceImpl.updateById");
        }
        // ------------开始业务----------------------
        expressRepository.save(express);
    }

    @Override
    public void updateByIdInBatch(List<Express> expresses) {
        // ------------------参数检验---------------
        if (CollUtil.isEmpty(expresses))
            throw new CustomException(ResultCode.PARAM_IS_BLANK, "ExpressServiceImpl.updateByIdInBatch");
        // ------------开始业务----------------------
        for (Express express: expresses) {
            this.updateById(express);
        }
    }

    @Override
    public Express findById(Integer id) {
        // ------------------参数检验---------------
        if (id == null)
            throw new CustomException(ResultCode.PARAM_IS_BLANK, "ExpressServiceImpl.findById");
        // ------------开始业务----------------------
        Optional<Express> optional = expressRepository.findByIdAndIsNotDelete(id);
        return optional.orElse(null);
    }

    @Override
    public List<Express> findByIdInBatch(List<Integer> ids) {
        // ------------------参数检验---------------
        if (CollUtil.isEmpty(ids))
            throw new CustomException(ResultCode.PARAM_IS_BLANK, "ExpressServiceImpl.findByIdInBatch");
        // ------------开始业务----------------------
        List<Express> expressList = new ArrayList<Express>();
        for (Integer id : ids) {
            expressList.add(this.findById(id));
        }
        return expressList;
    }

    @Override
    public PageData<Express> findAllByPage(PageWrap pageWrap) {
        // ------------------参数检验---------------
        if (!pageWrap.check()) {
            throw new CustomException(ResultCode.PARAM_IS_BLANK, "ExpressServiceImpl.findPage");
        }
        // ------------开始业务----------------------
        Pageable pageable = PageRequest.of(pageWrap.getPage(), pageWrap.getCapacity(), pageWrap.sortMethod());
        Page<Express> expressPage = expressRepository.getExpressPageIsNotDeleted(pageable);
        PageData<Express> pageData = PageData.from(expressPage);
        return pageData;
    }

    @Override
    public long countAll(Integer userId) {
        List<Express> all = this.findAll(userId);
        return all.size();
    }

    @Override
    public List<Express> findAll(Integer userId) {
        return expressRepository.findAllIsNotDelete(userId);
    }

    @Override
    public PageData<Express> queryAllByPage(PageWrap<Express> pageWrap) {
        // ------------------参数检验---------------
        if (!pageWrap.check()) {
            throw new CustomException(ResultCode.PARAM_IS_BLANK, "ExpressServiceImpl.findPage");
        }
        // ------------开始业务----------------------
        Pageable pageable = PageRequest.of(pageWrap.getPage(), pageWrap.getCapacity(), pageWrap.sortMethod());
        Express express = pageWrap.getModel();
        // 待实现
        return null;
    }

    @Override
    public void syncSystemData(Integer userId) {
        // 判断该userId是否有本年度的最新数据，没有则同步，有则不同步
        if (userId == 1) {
            return;
        }
        int thisYear = DateUtil.year(DateUtil.date());
        for (Express express : this.findAll(userId)) {
            int expressYear = DateUtil.year(express.getDate());
            if (expressYear == thisYear) {
                return;
            }
        }
        // 同步
        int adminId = 1;
        List<Express> adminList = this.findAll(adminId);
        for (Express express : adminList) {
            // 设置新的id
            Express express1 = new Express();
            BeanUtils.copyProperties(express, express1);
            express1.setUserID(userId);
            express1.setId(null);
            this.create(express1);
        }

    }

    @Override
    public List<Express> restoreToSys(Integer userId) {
        List<Express> expressList = expressRepository.findAllIsNotDelete(userId);
        int adminId = 1;
        List<Express> adminList = this.findAll(adminId);
        if (userId == 1) {
            return adminList;
        }
        List<Integer> ids = new ArrayList<Integer>();
        for (Express e: expressList) {
            ids.add(e.getId());
        }
        this.deleteByIdInBatch(ids);
//        expressRepository.deleteAll(expressList);
        for (Express express: adminList) {
            Express express1 = new Express();
            BeanUtils.copyProperties(express, express1);
            express1.setUserID(userId);
            express1.setId(null);
            this.create(express1);
        }
        List<Express> resultList = this.findAll(userId);

        return resultList;
    }

    @Override
    public List<Map> getAllExpressName(Integer userId) {
        List<Express> expressList = this.findAll(userId);
        List<String> expressNames = new ArrayList<>();
        List<Map> mapList = new ArrayList<Map>();
        for (Express express : expressList) {
            if (!expressNames.contains(express.getName())) {
                expressNames.add(express.getName());
                Map sellerNameAndIdsMap = new HashMap();
                sellerNameAndIdsMap.put("id", express.getId());
                sellerNameAndIdsMap.put("name", express.getName());
                mapList.add(sellerNameAndIdsMap);
            }
        }
        return mapList;
    }

//    @Override
//    public List<Integer> findIdsByName(Integer e, Integer u) {
//        List<Express> expressList = expressRepository.findIdsByName(e, u);
//        List<Integer> ids = new ArrayList<>();
//        for (Express express : expressList) {
//            int expressYear = DateUtil.year(express.getDate());
//            int thisYear = DateUtil.year(new Date());
//            if (expressYear == thisYear)
//                ids.add(express.getId());
//        }
//        return ids;
//    }

        @Override
        public List<Integer> findIdsByName(Integer e, Integer u) {
        List<Integer> ids = expressRepository.findIdsByName(e, u);
        return ids;
    }

    @Override
    public Integer findByNameWeightTargetOrigin(String expressName, Float weight, String origin, String target, Integer userId) {
        return expressRepository.findByNameWeightTargetOrigin(expressName, weight, origin, target, userId);
    }

    @Override
    public List<Express> queryAllByCondition(Express express) {
        String t = express.getTarget();
        Integer u = express.getUserId();
        String n = express.getName();
        String y = DateUtil.format(express.getDate(), "yyyy");
//        Integer y = Convert.toInt(year);
        if (t == null && u == null && y == null) {
            return this.findAll(u);
        } else if (t != null && n == null && y == null) {
            return expressRepository.findByTarget(t, u);
        } else if (t == null && n != null && y == null){
            return expressRepository.findByName(n, u);
        } else if (t == null && n == null && y != null){
            return expressRepository.findByYear(y, u);
        } else if (t != null && n != null && y == null) {
            return expressRepository.findByTargetAndName(t, n, u);
        } else if (t == null && n != null && y != null) {
            return expressRepository.findByNameAndYear(n, y, u);
        } else if (t != null && n == null && y != null) {
            return expressRepository.findByTargetAndYear(t, y, u);
        } else {
            return expressRepository.findByTargetAndNameAndYear(n, t, y, u);
        }
    }


}
